package org.light.exceltrnslator;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.light.core.ReportComb;
import org.light.domain.Domain;
import org.light.domain.Dropdown;
import org.light.domain.Field;
import org.light.domain.ManyToMany;
import org.light.domain.Prism;
import org.light.domain.Project;
import org.light.domain.ValidateInfo;
import org.light.exception.ValidateException;
import org.light.reports.EChartsCompareGridReport;
import org.light.reports.EChartsGridReport;
import org.light.reports.EChartsReport;
import org.light.utils.DomainUtil;
import org.light.utils.FieldUtil;
import org.light.utils.StringUtil;

public class ReportExcelTranslator {
	protected static Logger logger = Logger.getLogger(ReportExcelTranslator.class);
	
	public ReportComb translate(Project project,HSSFSheet sheet,List<Domain> domains,List<List<Domain>> datadomains) throws Exception {
		String reportName = readMetaField(sheet, "report");
		if ("echartsreport".equalsIgnoreCase(reportName)) {
			return translatReportCombData(project,sheet,domains,datadomains);
		}
		else if ("echartsgridreport".equalsIgnoreCase(reportName)) {
			return translatGridReportCombData(project,sheet,domains,datadomains);
		}
		else if ("echartscomparegridreport".equalsIgnoreCase(reportName)) {
			return translatCompareGridReportCombData(project,sheet,domains,datadomains);
		}
		return null;	
	}
	
	public ValidateInfo validateReportCombData(String reportName,String reportDmainName,String xAixsFieldsStr,String yNameFieldName,List<Domain> domains,List<List<Domain>> datadomains) {
		ValidateInfo info = new ValidateInfo();
		if (StringUtil.isBlank(reportDmainName)||StringUtil.isBlank(xAixsFieldsStr)||StringUtil.isBlank(yNameFieldName)) {
			info.addCompileError("报表"+reportName+"初始参数设置错误！");
		}
		Domain reportDomain = DomainUtil.findDomainInListOrReturnNull(domains,reportDmainName);
		if (reportDomain==null) info.addCompileError("报表"+reportName+"的reportDomain字段设置错误！");
		else {
			Field yName = reportDomain.findFieldByFieldName(yNameFieldName);
			if (yName==null) {
				info.addCompileError("报表"+reportName+"的yName字段设置错误！");
			}else if (yName instanceof Dropdown) {
				Domain target = DomainUtil.findDomainInListOrReturnNull(domains,((Dropdown) yName).getTargetName());
				if (target==null) info.addCompileError("报表"+reportName+"的yName下拉列表字段设置错误！");
			}
			List<Field> xAxisFields = new ArrayList<>();
			String [] xAxisNames = xAixsFieldsStr.split(",");
			for (String fn:xAxisNames) {
				Field f = reportDomain.findFieldByFieldName(fn);
				if (f==null)info.addCompileError("报表"+reportName+"的"+fn+"字段设置错误！");
				else if (!FieldUtil.isNumeric(f)) info.addCompileError("报表"+reportName+"的"+fn+"字段不是数值字段！");
			}
		}
		return info;
	}
	
	public EChartsReport translatReportCombData(Project project,HSSFSheet metaSheet,List<Domain> domains,List<List<Domain>> datadomains)  throws Exception{
		String reportName = metaSheet.getSheetName();
		String reportDmainName = readMetaField(metaSheet, "reportdomain");
		String xAixsFieldsStr = readMetaField(metaSheet, "xaxisfields");
		String yNameFieldName = readMetaField(metaSheet, "yname");
		ValidateInfo info = validateReportCombData(reportName,reportDmainName,xAixsFieldsStr,yNameFieldName,domains,datadomains);
		if (!info.success(true)) throw new ValidateException(info);
		Domain reportDomain = DomainUtil.findDomainInListOrReturnNull(domains,reportDmainName);
		Field yName = reportDomain.findFieldByFieldName(yNameFieldName);
		if (yName instanceof Dropdown) {
			Domain target = DomainUtil.findDomainInListOrReturnNull(domains,((Dropdown) yName).getTargetName());
			if (target!=null) ((Dropdown) yName).decorate(target);
		}
		List<Field> xAxisFields = new ArrayList<>();
		String [] xAxisNames = xAixsFieldsStr.split(",");
		for (String fn:xAxisNames) {
			Field f = reportDomain.findFieldByFieldName(fn);
			xAxisFields.add(f);
		}
		EChartsReport report = new EChartsReport(reportDomain,xAxisFields,yName);
		return report;
	}
	
	public EChartsGridReport translatGridReportCombData(Project project,HSSFSheet metaSheet,List<Domain> domains,List<List<Domain>> datadomains)  throws Exception{
		String reportName =  metaSheet.getSheetName();
		String reportDmainName = readMetaField(metaSheet, "reportdomain");
		String xAixsFieldsStr = readMetaField(metaSheet, "xaxisfields");
		String yNameFieldName = readMetaField(metaSheet, "yname");
		ValidateInfo info = validateReportCombData(reportName,reportDmainName,xAixsFieldsStr,yNameFieldName,domains,datadomains);
		if (!info.success(true)) throw new ValidateException(info);
		Domain reportDomain = DomainUtil.findDomainInList(domains,reportDmainName);
		Field yName = reportDomain.findFieldByFieldName(yNameFieldName);
		if (yName instanceof Dropdown) {
			Domain target = DomainUtil.findDomainInList(domains,((Dropdown) yName).getTargetName());
			((Dropdown) yName).decorate(target);
		}
		List<Field> xAxisFields = new ArrayList<>();
		String [] xAxisNames = xAixsFieldsStr.split(",");
		for (String fn:xAxisNames) {
			xAxisFields.add(reportDomain.findFieldByFieldName(fn));
		}
		EChartsGridReport report = new EChartsGridReport(reportDomain,xAxisFields,yName);
		return report;
	}
	
	public ValidateInfo validateCompareReportCombData(String reportName,String planDmainName,String planxAixsFieldsStr,String planyNameFieldName,String actionDmainName,String actionxAixsFieldsStr,String actionyNameFieldName,List<Domain> domains,List<List<Domain>> datadomains) {
		ValidateInfo info = new ValidateInfo();
		if (StringUtil.isBlank(planDmainName)||StringUtil.isBlank(planxAixsFieldsStr)||StringUtil.isBlank(planyNameFieldName)
				||StringUtil.isBlank(actionDmainName)||StringUtil.isBlank(actionxAixsFieldsStr)||StringUtil.isBlank(actionyNameFieldName)	) {
			info.addCompileError("报表"+reportName+"初始参数设置错误！");
		}
		Domain planDomain = DomainUtil.findDomainInListOrReturnNull(domains,planDmainName);
		if (planDomain==null) info.addCompileError("报表"+reportName+"的planDomain字段设置错误！");
		else {
			Field planyName = planDomain.findFieldByFieldName(planyNameFieldName);
			if (planyName==null) {
				info.addCompileError("报表"+reportName+"的planyName字段设置错误！");
			}else if (planyName instanceof Dropdown) {
				Domain target = DomainUtil.findDomainInListOrReturnNull(domains,((Dropdown) planyName).getTargetName());
				if (target==null) info.addCompileError("报表"+reportName+"的planyName下拉列表字段设置错误！");
			}
			List<Field> planxAxisFields = new ArrayList<>();
			String [] planxAxisNames = planxAixsFieldsStr.split(",");
			for (String fn:planxAxisNames) {
				Field f = planDomain.findFieldByFieldName(fn);
				if (f==null)info.addCompileError("报表"+reportName+"的planDomain的"+fn+"字段设置错误！");
				else if (!FieldUtil.isNumeric(f)) info.addCompileError("报表"+reportName+"的planDomain的"+fn+"字段不是数值字段！");
			}
		}
		
		Domain actionDomain = DomainUtil.findDomainInListOrReturnNull(domains,actionDmainName);
		if (actionDomain==null) info.addCompileError("报表"+reportName+"的actionDomain字段设置错误！");
		else {
			Field actionyName = actionDomain.findFieldByFieldName(actionyNameFieldName);
			if (actionyName==null) {
				info.addCompileError("报表"+reportName+"的actionyName字段设置错误！");
			}else if (actionyName instanceof Dropdown) {
				Domain target = DomainUtil.findDomainInListOrReturnNull(domains,((Dropdown) actionyName).getTargetName());
				if (target==null) info.addCompileError("报表"+reportName+"的actionyName下拉列表字段设置错误！");
			}
			List<Field> actionxAxisFields = new ArrayList<>();
			String [] actionxAxisNames = actionxAixsFieldsStr.split(",");
			for (String fn:actionxAxisNames) {
				Field f = actionDomain.findFieldByFieldName(fn);
				if (f==null)info.addCompileError("报表"+reportName+"的actionDomain的"+fn+"字段设置错误！");
				else if (!FieldUtil.isNumeric(f)) info.addCompileError("报表"+reportName+"的actionDomain的"+fn+"字段不是数值字段！");
			}
		}
		return info;
	}
	
	public EChartsCompareGridReport translatCompareGridReportCombData(Project project,HSSFSheet metaSheet,List<Domain> domains,List<List<Domain>> datadomains)  throws Exception{
		String reportName =  metaSheet.getSheetName();
		String planDmainName = readMetaField(metaSheet, "plandomain");
		String planxAixsFieldsStr = readMetaField(metaSheet, "planxaxisfields");
		String planyNameFieldName = readMetaField(metaSheet, "planyname");
		
		String actionDmainName = readMetaField(metaSheet, "actiondomain");
		String actionxAixsFieldsStr = readMetaField(metaSheet, "actionxaxisfields");
		String actionyNameFieldName = readMetaField(metaSheet, "actionyname");

		ValidateInfo info = validateCompareReportCombData(reportName,planDmainName,planxAixsFieldsStr,planyNameFieldName,actionDmainName,actionxAixsFieldsStr,actionyNameFieldName,domains,datadomains);
		if (!info.success(true)) throw new ValidateException(info);
		
		Domain planDomain = DomainUtil.findDomainInList(domains,planDmainName);
		Field planyName = planDomain.findFieldByFieldName(planyNameFieldName);		
		if (planyName instanceof Dropdown) {
			Domain target = DomainUtil.findDomainInList(domains,((Dropdown) planyName).getTargetName());
			((Dropdown) planyName).decorate(target);
		}
		List<Field> planxAxisFields = new ArrayList<>();
		String [] planxAxisNames = planxAixsFieldsStr.split(",");
		for (String fn:planxAxisNames) {
			planxAxisFields.add(planDomain.findFieldByFieldName(fn));
		}
		
		Domain actionDomain = DomainUtil.findDomainInList(domains,actionDmainName);
		Field actionyName = actionDomain.findFieldByFieldName(actionyNameFieldName);
		if (actionyName instanceof Dropdown) {
			Domain target = DomainUtil.findDomainInList(domains,((Dropdown) actionyName).getTargetName());
			((Dropdown) actionyName).decorate(target);
		}
		List<Field> actionxAxisFields = new ArrayList<>();
		String [] actionxAxisNames = actionxAixsFieldsStr.split(",");
		for (String fn:actionxAxisNames) {
			actionxAxisFields.add(actionDomain.findFieldByFieldName(fn));
		}
		EChartsCompareGridReport report = new EChartsCompareGridReport(planDomain,planxAxisFields,planyName,actionDomain,actionxAxisFields,actionyName);
		return report;
	}

	public Prism translatePrism(HSSFSheet prismSheet) {
		Prism prism = new Prism();
		return prism;
	}


	public boolean validateMetaField(String fieldMeta) {
		switch (fieldMeta) {
			case "id":
			case "domainname":
			case "activefield":
			case "field":
			case "dropdown":
			case "manytomanyslave":
				return true;
			default:
				return false;
		}
	}
	
	public boolean validateFieldType(String fieldMeta,String fieldType) {
		if ("dropdown".equals(fieldMeta)||"manytomanyslave".equals(fieldMeta)) {
			return true;
		}else {
			switch (fieldType) {
			case "int":
			case "Integer":
			case "long":
			case "Long":
			case "boolean":
			case "Boolean":
			case "double":
			case "Double":
			case "float":
			case "Float":
			case "string":
			case "String":
			case "decimal":
			case "Decimal":
			case "BigDecimal":
			case "image":
			case "Image":
				return true;
			default:
				return false;
		}
		}
	}
	
	public boolean validateSqlFieldType(String fieldType) {
			fieldType = fieldType.toLowerCase();
			switch (fieldType) {
			case "char":
			case "nchar":
			case "varchar":
			case "varchar2":
			case "nvarchar":
			case "tinytext":
			case "longtext":
			case "text":
			case "ntext":
			case "tinyint":
			case "smallint":
			case "mediumint":
			case "bigint":
			case "numeric":
			case "decimal":
			case "real":
				return true;
			default:
				return false;
		}
	}
	
	public String parseSqlFieldType(String fieldType) {
		String myfieldType = fieldType.toLowerCase();
		switch (myfieldType) {
		case "char":
		case "nchar":
		case "varchar":
		case "varchar2":
		case "nvarchar":
		case "tinytext":
		case "longtext":
		case "text":
		case "ntext":
			return "String";
		case "tinyint":
		case "smallint":
		case "mediumint":
			return "Integer";
		case "bigint":
			return "Long";
		case "numeric":
		case "decimal":
		case "real":
			return "Double";
		default:
			return fieldType;
		}
	}
	
	public Field readDomainField(HSSFSheet sheet, int columIndex, int metaFieldIndex, int fieldIndex,
			int fieldTypeIndex,int fieldLengthIndex, int fieldLabelIndex, Domain domain,String dbType,Boolean ignoreWarning) throws ValidateException {
		Field f = new Field();
		String metafield = readFieldMeta(sheet, columIndex, metaFieldIndex,dbType);
		logger.debug("JerryDebug:" + metafield);
		String fieldname = sheet.getRow(fieldIndex).getCell(columIndex).getStringCellValue().trim().replace("\'","");
		if (fieldname.contains("_")) fieldname = StringUtil.changeTableColumtoDomainField(fieldname);
		String fieldType = sheet.getRow(fieldTypeIndex).getCell(columIndex).getStringCellValue().trim().replace("\'","");
		String fieldLength =  fieldLengthIndex < 0 ? "" : getCellStringValue(sheet.getRow(fieldLengthIndex).getCell(columIndex)).trim().replace("\'","");
		String fieldLabel = getCellStringValue(sheet.getRow(fieldLabelIndex).getCell(columIndex)).replace("\'","");
		long fieldSerial = columIndex*100;
		ValidateInfo info = new ValidateInfo();
		if (!validateMetaField(metafield)) {
			info.addCompileError("域对象"+domain.getStandardName()+"元字段" + metafield + "设置错误！");
		}
		if (validateSqlFieldType(fieldType)) {
			info.addCompileWarning("域对象"+domain.getStandardName()+"字段类型" + fieldType + "为SQL类型！");
			fieldType = parseSqlFieldType(fieldType);
		}
		if (!validateFieldType(metafield,fieldType)) {
			info.addCompileError("域对象"+domain.getStandardName()+"字段类型" + fieldType + "设置错误！");
		}
		if (!StringUtil.isLowerCaseLetter(fieldname)) {
			info.addCompileError("域对象"+domain.getStandardName()+"字段" + fieldname + "未使用小写英文字母开头！");
		}
		if (fieldname.length() >= 2 && !StringUtil.isLowerCaseLetterPosition(fieldname,1)){
			info.addCompileError("域对象"+domain.getStandardName()+"字段" + fieldname + "第二个字母未使用小写英文字母！");
		}
		
		if (!StringUtil.isBlank(metafield)
				&& (metafield.equalsIgnoreCase("id") || metafield.equalsIgnoreCase("domianid")
						|| metafield.equalsIgnoreCase("domainname") || metafield.equalsIgnoreCase("active")
						|| metafield.equalsIgnoreCase("activefield") || metafield.equalsIgnoreCase("field"))) {
			if (!StringUtil.isBlank(fieldType))
				f.setFieldType(fieldType);
			if (!StringUtil.isBlank(fieldLength))
				f.setLengthStr(fieldLength);
			if (!StringUtil.isBlank(fieldLabel)) {
				f.setLabel(fieldLabel);
				domain.putFieldLabel(fieldname, fieldLabel);
			}
			if (!StringUtil.isBlank(fieldname))
				f.setFieldName(fieldname);
			if (!info.success(ignoreWarning))
				throw new ValidateException(info);
			else {
				f.setSerial(fieldSerial);
				return f;
			}
				
		} else {
			info.addCompileError("字段解析错误");
			throw new ValidateException(info);
		}
	}

	public Dropdown readDropdown(HSSFSheet sheet, int columIndex, int metaFieldIndex, int fieldIndex,
			int fieldTypeIndex, int fieldLabelIndex,Boolean ignoreWarning) throws ValidateException {
		String metafield = sheet.getRow(metaFieldIndex).getCell(columIndex).getStringCellValue().trim();
		String fieldname = sheet.getRow(fieldIndex).getCell(columIndex).getStringCellValue().trim().replace("\'","");
		if (fieldname.contains("_")) fieldname = StringUtil.changeTableColumtoDomainField(fieldname);
		String fieldType = sheet.getRow(fieldTypeIndex).getCell(columIndex).getStringCellValue().trim().replace("\'","");
		String fieldLabel = sheet.getRow(fieldLabelIndex).getCell(columIndex).getStringCellValue().trim().replace("\'","");
		ValidateInfo info = new ValidateInfo();
		if (!StringUtil.isLowerCaseLetter(fieldname)) {
			info.addCompileError("下拉列表字段" + fieldname + "未使用小写英文字母开头！");
		}
		if (metafield != null && !metafield.equals("") && metafield.equalsIgnoreCase("dropdown")) {
			Dropdown dp = new Dropdown(fieldType);
			dp.setAliasName(fieldname);
			dp.setFieldName(dp.getAliasName());
			dp.setLabel(fieldLabel);
			if (!info.success(ignoreWarning))
				throw new ValidateException(info);
			else
				return dp;
		} else {
			info.addCompileError("字段解析错误");
			throw new ValidateException(info);
		}
	}

	public String readFieldMeta(HSSFSheet sheet, int columIndex, int metaFieldIndex, String dbType) {
		String metafield = getCellStringValue(sheet.getRow(metaFieldIndex).getCell(columIndex));
		return metafield;
	}

	public String readManyToManyName(HSSFSheet sheet, int columIndex, int metaFieldIndex, int fieldIndex,
			int fieldTypeIndex, int fieldLabelIndex) throws ValidateException {
		String metafield = sheet.getRow(metaFieldIndex).getCell(columIndex).getStringCellValue().trim();
		String fieldType = sheet.getRow(fieldTypeIndex).getCell(columIndex).getStringCellValue().trim();
		if (fieldType.contains("_")) fieldType = StringUtil.capFirst(StringUtil.changeTableColumtoDomainField(fieldType));
		fieldType = StringUtil.capFirst(fieldType);
		if (metafield != null && !metafield.equals("") && metafield.equalsIgnoreCase("manytomanyslave")) {
			return fieldType;
		} else {
			throw new ValidateException("字段解析错误");
		}
	}
	
	public String readManyToManyAlias(HSSFSheet sheet, int columIndex, int metaFieldIndex, int fieldIndex,
			int fieldTypeIndex, int fieldLabelIndex) throws ValidateException {
		String metafield = sheet.getRow(metaFieldIndex).getCell(columIndex).getStringCellValue().trim();
		String field = sheet.getRow(fieldIndex).getCell(columIndex).getStringCellValue().trim();
		if (field.contains("_")) field = StringUtil.changeTableColumtoDomainField(field);
		field = StringUtil.capFirst(field);
		if (metafield != null && !metafield.equals("") && metafield.equalsIgnoreCase("manytomanyslave")) {
			return field;
		} else { 
			throw new ValidateException("字段解析错误");
		}
	}
	
	public String readManyToManyAliasLabel(HSSFSheet sheet, int columIndex, int metaFieldIndex, int fieldIndex,
			int fieldTypeIndex, int fieldLabelIndex) throws ValidateException {
		String metafield = sheet.getRow(metaFieldIndex).getCell(columIndex).getStringCellValue().trim();
		String field = sheet.getRow(fieldLabelIndex).getCell(columIndex).getStringCellValue().trim();
		if (metafield != null && !metafield.equals("") && metafield.equalsIgnoreCase("manytomanyslave")) {
			return field;
		} else {
			throw new ValidateException("字段解析错误");
		}
	}

	public String readMetaField(HSSFSheet metaSheet, String key) {
		Cell c = locateKeyCell(metaSheet, key);
		if (c == null)
			return "";
		else
			// return
			// metaSheet.getRow(c.getRowIndex()).getCell(c.getColumnIndex() +
			// 1).getStringCellValue();
			return this.getCellStringValue(metaSheet.getRow(c.getRowIndex()).getCell(c.getColumnIndex() + 1)).trim();
	}

	public Cell locateKeyCell(HSSFSheet metaSheet, String key) {
		int rowbegin = metaSheet.getFirstRowNum();
		int rowend = metaSheet.getLastRowNum();
		for (int i = rowbegin; i <= rowend; i++) {
			Row r = metaSheet.getRow(i);
			if(r!=null) {
				for (int j = r.getFirstCellNum(); j <= r.getLastCellNum(); j++) {
					Cell c = r.getCell(j);
					if (c != null && this.getCellStringValue(c).equalsIgnoreCase(key))
						return c;
				}
			}
		}
		return null;
	}

	public List<Domain> readDomainListWithData(HSSFSheet sheet, Domain templateDomain, String dbtype,boolean ignoreWarning) throws ValidateException {
		List<Domain> resultList = new ArrayList<Domain>();
		Cell metaCell = locateKeyCell(sheet, "元字段类型");
		Cell dataCell = locateKeyCell(sheet, "数据");
		Cell fieldCell = locateKeyCell(sheet, "字段");
		
		ValidateInfo vInfo = new ValidateInfo();
		for (int i = dataCell.getRowIndex(); i < findOutLastDataRowIndex(sheet, findOutIdColIndex(sheet, dbtype),
				dataCell.getRowIndex(), dbtype); i++) {
			Domain targetDomain = (Domain) templateDomain.deepClone();
			for (Field f : templateDomain.getFields()) {
				if (f instanceof Dropdown) {
					Dropdown dp = (Dropdown) f;
					String fieldValue = StringUtil.filterSingleQuote(readDomainFieldValue(sheet, dp.getAliasName(),
							fieldCell.getColumnIndex() + 1,metaCell.getRowIndex(),  fieldCell.getRowIndex(), i, dbtype));
					logger.debug("JerryDebug:dropdown:fieldvalue:" + fieldValue);
					if (!DomainUtil.validateId(fieldValue)) vInfo.addCompileError("域对象"+targetDomain.getStandardName()+"的下拉列表"+f.getFieldName()+"值有错！");
					if (!StringUtil.isBlank(fieldValue))
						targetDomain.setFieldValue(dp.getAliasName(), fieldValue);
					else
						targetDomain.setFieldValue(dp.getAliasName(), fieldValue);

					logger.debug(
							"JerryDebug:dropdown:value:" + targetDomain.getField(dp.getAliasName()).getFieldValue());
				} else {
					String fieldValue = StringUtil.filterSingleQuote(readDomainFieldValue(sheet, f.getFieldName(),
							fieldCell.getColumnIndex() + 1,metaCell.getRowIndex(),  fieldCell.getRowIndex(), i, dbtype));
					logger.debug("JerryDebug:readFieldWithData:field:fieldValue"+f.getFieldName()+":"+fieldValue);
					if (targetDomain.getDomainId()!=null&&f.getFieldName().equals(targetDomain.getDomainId().getFieldName())&&!DomainUtil.validateId(fieldValue))  vInfo.addCompileError("域对象"+targetDomain.getStandardName()+"的主键"+f.getFieldName()+"值有错！");
					if (!StringUtil.isBlank(fieldValue))
						targetDomain.getField(f.getFieldName()).setFieldValue(fieldValue);
					else
						targetDomain.getField(f.getFieldName()).setFieldValue("");
				}
			}
			for (ManyToMany mtm:targetDomain.getManyToManies()){
				String fieldValue = StringUtil.filterSingleQuote(readDomainFieldValue(sheet, mtm.getSlaveAlias(),
						fieldCell.getColumnIndex() + 1, metaCell.getRowIndex(), fieldCell.getRowIndex(), i, dbtype));
				
				mtm.setMaster(targetDomain);					
				mtm.setValues(fieldValue);
				if (targetDomain.hasDomainId()) mtm.setMasterValue(targetDomain.getDomainId().getFieldValue());
				else  throw new ValidateException("遗留域对象" + targetDomain.getStandardName() + "不可作为多对多主对象。");
			}
			resultList.add(targetDomain);
		}
		if (!vInfo.isSuccess(ignoreWarning)) throw new ValidateException(vInfo);
		else return resultList;
	}
	
	public int findOutIdColIndex(HSSFSheet sheet, String dbType) {
		Cell metaFieldCell = locateKeyCell(sheet, "元字段类型");
		for (int i = metaFieldCell.getColumnIndex() + 1; i < sheet.getRow(metaFieldCell.getRowIndex())
				.getLastCellNum(); i++) {
			if (sheet.getRow(metaFieldCell.getRowIndex()).getCell(i).getStringCellValue().equals("id")) {
				return i;
			}
		}
		return metaFieldCell.getColumnIndex() + 1;
	}

	public int findOutLastDataRowIndex(HSSFSheet sheet, int idColIndex, int beginRowIndex, String dbtype) {
		for (int i = beginRowIndex; i <= sheet.getLastRowNum(); i++) {
			if (sheet.getRow(i)==null ||sheet.getRow(i).getCell(idColIndex)==null || StringUtil.isBlank(getCellStringValue(sheet.getRow(i).getCell(idColIndex))))
				return i;
		}
		return sheet.getLastRowNum()+1;
	}

	public String readDomainFieldValue(HSSFSheet sheet, String fieldName, int beginColIndex, int metaFieldRowIndex,int fieldNameRowIndex,
			int rowIndex, String dbtype) throws ValidateException{
		for (int i = beginColIndex; i < sheet.getRow(fieldNameRowIndex).getLastCellNum(); i++) {
			Cell metac = sheet.getRow(metaFieldRowIndex).getCell(i);
			Cell c = sheet.getRow(fieldNameRowIndex).getCell(i);			
			String metaField = metac.getStringCellValue();
			String cellfieldName = c.getStringCellValue();
			if (cellfieldName.contains("_")) cellfieldName = StringUtil.changeTableColumtoDomainField(cellfieldName);
			if (metaField.equalsIgnoreCase("manytomanyslave")) {
				cellfieldName = StringUtil.capFirst(cellfieldName);
			}else {
				cellfieldName = StringUtil.lowerFirst(cellfieldName);
			}
			if (!StringUtil.isBlank(cellfieldName) && cellfieldName.equals(fieldName)) {
				return getCellStringValue(sheet.getRow(rowIndex).getCell(i));
			}
		}
		return "";
	}

	public String getCellStringValue(Cell c) {
		if (c==null) return "";
		if (c.getCellType() == CellType.STRING) {
			String retVal = c.getStringCellValue();
			if (!StringUtil.isBlank(retVal)&&retVal.charAt(0)=='\'') return retVal.substring(1,retVal.length());
			else if (StringUtil.isBlank(retVal)) return "";
			else return retVal;
		}
			
		else if (c.getCellType() == CellType.NUMERIC) {
			short format = c.getCellStyle().getDataFormat();
			if (format == 14 || format == 31 || format == 57 || format == 58) {
				DateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
				Date date = DateUtil.getJavaDate(c.getNumericCellValue());
				String value = formater.format(date);
				return value;
			} else if (format == 20 || format == 32) {
				DateFormat formater = new SimpleDateFormat("HH:mm");
				Date date = DateUtil.getJavaDate(c.getNumericCellValue());
				String value = formater.format(date);
				return value;
			}
			double dis = c.getNumericCellValue() - Math.round(c.getNumericCellValue());
			if (dis > 0.0001d) {
				return "" + c.getNumericCellValue();
			} else {
				return "" + (long) Math.round(c.getNumericCellValue());
			}
		} 
			return "";
	}
	

	public static void main(String[] args) {
		
	}

}
